package main

import (
	"fmt"
	"strconv"
	"time"
)

func task() {
	for index := 0; index < 10; index++ {
		fmt.Println("task run " + strconv.Itoa(index))
		time.Sleep(time.Second) // 休息 1S
	}
}

/*
MPG模型：
https://studygolang.com/articles/17325
简单解释：
M: (Machine)代表着真正的执行计算资源。在绑定有效的p后，进入schedule循环；而schedule循环的机制大致是从各种队列、
	p的本地队列中获取G，切换到G的执行栈上并执行G的函数，调用goexit做清理工作并回到m，如此反复。M并不保留G状态，
	这是G可以跨M调度的基础。

P: 表示逻辑processor，P的数量决定了系统内最大可并行的G的数量（前提：系统的物理cpu核数>=P的数量）；P的最大作用
	还是其拥有的各种G对象队列、链表、一些cache和状态。

G: 表示goroutine，存储了goroutine的执行stack信息、goroutine状态以及goroutine的任务函数等

简单来讲：
M指的是Machine，一个M直接关联了一个内核线程。
P指的是”processor”，代表了M所需的上下文环境，也是处理用户级代码逻辑的处理器。
G指的是Goroutine，其实本质上也是一种轻量级的线程。

*/
func main() {

	go task() // 启动协程

	for index := 0; index < 10; index++ {
		fmt.Println("main run " + strconv.Itoa(index))
		time.Sleep(time.Second) // 休息 1S
	}

}
